package game;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

public class MatchThreeGame extends JFrame {
    private static final int ROWS = 8;
    private static final int COLS = 8;
    private static final int NUM_TYPES = 5;
    private int[][] board;
    private JButton[][] buttons;
    private int firstX = -1, firstY = -1;
    // 定义每种类型对应的颜色
    private static final Color[] COLORS = {Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.MAGENTA};

    public MatchThreeGame() {
        board = new int[ROWS][COLS];
        buttons = new JButton[ROWS][COLS];
        initializeBoard();
        setupUI();
    }

    private void initializeBoard() {
        Random random = new Random();
        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLS; j++) {
                board[i][j] = random.nextInt(NUM_TYPES);
            }
        }
    }

    private void setupUI() {
        setTitle("消消乐游戏");
        setSize(400, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new GridLayout(ROWS, COLS));

        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLS; j++) {
                buttons[i][j] = new JButton();
                // 设置按钮背景颜色
                buttons[i][j].setBackground(COLORS[board[i][j]]);
                buttons[i][j].setOpaque(true);
                buttons[i][j].setBorderPainted(false);
                final int x = i;
                final int y = j;
                buttons[i][j].addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (firstX == -1) {
                            firstX = x;
                            firstY = y;
                        } else {
                            if (swap(firstX, firstY, x, y)) {
                                updateBoardUI();
                            }
                            firstX = -1;
                            firstY = -1;
                        }
                    }
                });
                add(buttons[i][j]);
            }
        }
        setVisible(true);
    }

    private void updateBoardUI() {
        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLS; j++) {
                // 更新按钮背景颜色
                buttons[i][j].setBackground(COLORS[board[i][j]]);
            }
        }
    }

    public boolean swap(int x1, int y1, int x2, int y2) {
        if (isValidMove(x1, y1, x2, y2)) {
            int temp = board[x1][y1];
            board[x1][y1] = board[x2][y2];
            board[x2][y2] = temp;
            if (hasMatches()) {
                removeMatches();
                refillBoard();
                return true;
            } else {
                // 如果交换后没有匹配，交换回来
                temp = board[x1][y1];
                board[x1][y1] = board[x2][y2];
                board[x2][y2] = temp;
                return false;
            }
        }
        return false;
    }

    private boolean isValidMove(int x1, int y1, int x2, int y2) {
        return (Math.abs(x1 - x2) + Math.abs(y1 - y2) == 1) &&
                x1 >= 0 && x1 < ROWS && y1 >= 0 && y1 < COLS &&
                x2 >= 0 && x2 < ROWS && y2 >= 0 && y2 < COLS;
    }

    private boolean hasMatches() {
        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLS; j++) {
                if (checkHorizontalMatch(i, j) || checkVerticalMatch(i, j)) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean checkHorizontalMatch(int row, int col) {
        if (col <= COLS - 3) {
            int type = board[row][col];
            return board[row][col + 1] == type && board[row][col + 2] == type;
        }
        return false;
    }

    private boolean checkVerticalMatch(int row, int col) {
        if (row <= ROWS - 3) {
            int type = board[row][col];
            return board[row + 1][col] == type && board[row + 2][col] == type;
        }
        return false;
    }

    private void removeMatches() {
        boolean[][] toRemove = new boolean[ROWS][COLS];
        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLS; j++) {
                if (checkHorizontalMatch(i, j)) {
                    toRemove[i][j] = true;
                    toRemove[i][j + 1] = true;
                    toRemove[i][j + 2] = true;
                }
                if (checkVerticalMatch(i, j)) {
                    toRemove[i][j] = true;
                    toRemove[i + 1][j] = true;
                    toRemove[i + 2][j] = true;
                }
            }
        }
        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLS; j++) {
                if (toRemove[i][j]) {
                    board[i][j] = -1;
                }
            }
        }
    }

    private void refillBoard() {
        for (int j = 0; j < COLS; j++) {
            int emptyIndex = ROWS - 1;
            for (int i = ROWS - 1; i >= 0; i--) {
                if (board[i][j] != -1) {
                    board[emptyIndex][j] = board[i][j];
                    if (emptyIndex != i) {
                        board[i][j] = -1;
                    }
                    emptyIndex--;
                }
            }
            Random random = new Random();
            for (int i = 0; i <= emptyIndex; i++) {
                board[i][j] = random.nextInt(NUM_TYPES);
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new MatchThreeGame();
            }
        });
    }
}